home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / term-source.lha / termDial.c < prev    next >
C/C++ Source or Header  |  1995-09-26  |  42KB  |  1,885 lines

  1. /*
  2. **    termDial.c
  3. **
  4. **    The dialing routine as called by the phonebook
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* Panel gadget IDs. */
  15.  
  16. enum    {    GAD_CALLING=1,GAD_TIME,GAD_NOTE,
  17.             GAD_SKIP,GAD_REMOVE,GAD_ONLINE,GAD_ABORT
  18.         };
  19.  
  20. STATIC VOID __stdargs
  21. PrintBox(LayoutHandle *Handle,LONG Box,LONG Line,STRPTR String,...)
  22. {
  23.     UBYTE     LocalBuffer[256];
  24.     va_list     VarArgs;
  25.  
  26.     va_start(VarArgs,String);
  27.     VSPrintf(LocalBuffer,String,VarArgs);
  28.     va_end(VarArgs);
  29.  
  30.     LT_SetAttributes(Handle,Box,
  31.         LABX_Index,    Line,
  32.         LABX_Text,    LocalBuffer,
  33.     TAG_DONE);
  34. }
  35.  
  36. STATIC BOOL __regargs
  37. SendSomeCommand(LayoutHandle *Handle,STRPTR Command,STRPTR Message,STRPTR ErrorMessage)
  38. {
  39.     PrintBox(Handle,GAD_NOTE,0,Message);
  40.  
  41.     FlowInit(TRUE);
  42.  
  43.     SerialCommand(Command);
  44.  
  45.     WaitTime(1,0);
  46.  
  47.     HandleSerial();
  48.  
  49.     if(FlowInfo . Changed && FlowInfo . Error)
  50.     {
  51.         PrintBox(Handle,GAD_NOTE,0,ErrorMessage);
  52.  
  53.         WakeUp(Handle -> Window,SOUND_ERROR);
  54.  
  55.         return(TRUE);
  56.     }
  57.     else
  58.         return(FALSE);
  59. }
  60.  
  61.     /* BuildName(STRPTR Name):
  62.      *
  63.      *    Build a file name from a BBS name and the current date.
  64.      */
  65.  
  66. STATIC VOID __regargs
  67. BuildName(STRPTR Name,STRPTR Date)
  68. {
  69.     if(Date[0])
  70.     {
  71.         WORD    NameLen = strlen(Name),
  72.                 DateLen = strlen(Date),
  73.                 Delta;
  74.  
  75.         if((Delta = NameLen + 1 + DateLen - 32) > 0)
  76.             Name[NameLen - Delta] = 0;
  77.  
  78.         strcat(Name,"_");
  79.         strcat(Name,Date);
  80.     }
  81. }
  82.  
  83.     /* OpenAutoCaptureFile(STRPTR SomeName):
  84.      *
  85.      *    Open a capture file.
  86.      */
  87.  
  88. STATIC VOID __regargs
  89. OpenAutoCaptureFile(STRPTR SomeName)
  90. {
  91.     UBYTE            SharedBuffer[MAX_FILENAME_LENGTH],
  92.                     Name[50],
  93.                     Date[20],
  94.                     Time[20];
  95.     struct DateTime    DateTime;
  96.  
  97.         /* Get the current time and date. */
  98.  
  99.     DateStamp(&DateTime . dat_Stamp);
  100.  
  101.         /* Prepare for date conversion. */
  102.  
  103.     DateTime . dat_Format    = FORMAT_DOS;
  104.     DateTime . dat_Flags    = 0;
  105.     DateTime . dat_StrDay    = NULL;
  106.     DateTime . dat_StrDate    = Date;
  107.     DateTime . dat_StrTime    = Time;
  108.  
  109.         /* Convert the date. */
  110.  
  111.     if(DateToStr(&DateTime))
  112.     {
  113.             /* Remember the BBS name. */
  114.  
  115.         strcpy(Name,SomeName);
  116.  
  117.             /* Append the creation date if necessary. */
  118.  
  119.         if(Config -> CaptureConfig -> AutoCaptureDate == AUTOCAPTURE_DATE_NAME)
  120.             BuildName(Name,Date);
  121.  
  122.             /* Make it a reasonable name. */
  123.  
  124.         FixName(Name);
  125.  
  126.             /* Get the capture file path. */
  127.  
  128.         strcpy(SharedBuffer,Config -> CaptureConfig -> CapturePath);
  129.  
  130.             /* Try to build a valid file and path name. */
  131.  
  132.         if(AddPart(SharedBuffer,Name,MAX_FILENAME_LENGTH))
  133.         {
  134.                 /* Is the capture file still open? */
  135.  
  136.             if(FileCapture)
  137.             {
  138.                     /* Close the file. */
  139.  
  140.                 BufferClose(FileCapture);
  141.  
  142.                 FileCapture = NULL;
  143.  
  144.                     /* Any data written? */
  145.  
  146.                 if(!GetFileSize(CaptureName))
  147.                     DeleteFile(CaptureName);
  148.                 else
  149.                 {
  150.                     AddProtection(CaptureName,FIBF_EXECUTE);
  151.  
  152.                     if(Config -> MiscConfig -> CreateIcons)
  153.                         AddIcon(CaptureName,FILETYPE_TEXT,TRUE);
  154.                 }
  155.             }
  156.  
  157.                 /* Try to append the new data. */
  158.  
  159.             if(FileCapture = BufferOpen(SharedBuffer,"a"))
  160.             {
  161.                     /* Set the menu checkmark. */
  162.  
  163.                 CheckItem(MEN_CAPTURE_TO_FILE,TRUE);
  164.  
  165.                     /* Remember the current capture file name. */
  166.  
  167.                 strcpy(CaptureName,SharedBuffer);
  168.  
  169.                     /* Add the creation date if necessary. */
  170.  
  171.                 if(Config -> CaptureConfig -> AutoCaptureDate == AUTOCAPTURE_DATE_INCLUDE)
  172.                 {
  173.                     UBYTE DateTimeBuffer[256];
  174.  
  175.                     if(FormatStamp(&DateTime . dat_Stamp,NULL,NULL,DateTimeBuffer,FALSE))
  176.                         BPrintf(FileCapture,LocaleString(MSG_DIALPANEL_FILE_CREATED_TXT),DateTimeBuffer);
  177.                 }
  178.             }
  179.             else
  180.                 CheckItem(MEN_CAPTURE_TO_FILE,FALSE);
  181.  
  182.             ConOutputUpdate();
  183.         }
  184.     }
  185. }
  186.  
  187.     /* Connect(struct PhoneNode *DialNode,STRPTR NumberBuffer):
  188.      *
  189.      *    Perform connect action(s).
  190.      */
  191.  
  192. STATIC VOID __regargs
  193. Connect(struct PhoneNode *DialNode,STRPTR NumberBuffer)
  194. {
  195.     if(DialNode -> Entry)
  196.     {
  197.         UpdateConfig(DialNode -> Entry -> Config,Config);
  198.  
  199.         ConfigChanged = FALSE;
  200.  
  201.         MakeCall(DialNode -> Entry -> Header -> Name,NumberBuffer);
  202.  
  203.         ObtainSemaphore(&PatternSemaphore);
  204.  
  205.         ChosenPattern = FindTimeDate(PatternList,NumberBuffer);
  206.  
  207.         SelectTime(DialNode -> Entry,ChosenPattern,NULL);
  208.  
  209.         ChosenEntry    = DialNode -> Entry;
  210.         WhichUnit    = DT_FIRST_UNIT;
  211.         CurrentPay    = 0;
  212.         SendStartup    = TRUE;
  213.  
  214.         ReleaseSemaphore(&PatternSemaphore);
  215.  
  216.         strcpy(Password,DialNode -> Entry -> Header -> Password);
  217.         strcpy(UserName,DialNode -> Entry -> Header -> UserName);
  218.  
  219.         strcpy(CurrentBBSName,DialNode -> Entry -> Header -> Name);
  220.         strcpy(CurrentBBSComment,DialNode -> Entry -> Header -> Comment);
  221.  
  222.         strcpy(CurrentBBSNumber,NumberBuffer);
  223.  
  224.         if(DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  225.         {
  226.             OnlinePlus = DialNode -> Entry -> Config -> ModemConfig -> TimeToConnect;
  227.  
  228.             if(DialNode -> Entry -> Config -> ModemConfig -> ConnectLimit > 0 && DialNode -> Entry -> Config -> ModemConfig -> ConnectLimitMacro[0])
  229.             {
  230.                 LimitCount = DialNode -> Entry -> Config -> ModemConfig -> ConnectLimit;
  231.  
  232.                 strcpy(LimitMacro,DialNode -> Entry -> Config -> ModemConfig -> ConnectLimitMacro);
  233.             }
  234.             else
  235.                 LimitCount = -1;
  236.         }
  237.         else
  238.         {
  239.             OnlinePlus = Config -> ModemConfig -> TimeToConnect;
  240.  
  241.             if(Config -> ModemConfig -> ConnectLimit > 0 && Config -> ModemConfig -> ConnectLimitMacro[0])
  242.             {
  243.                 LimitCount = Config -> ModemConfig -> ConnectLimit;
  244.  
  245.                 strcpy(LimitMacro,Config -> ModemConfig -> ConnectLimitMacro);
  246.             }
  247.             else
  248.                 LimitCount = -1;
  249.         }
  250.  
  251.         LogAction(LocaleString(MSG_DIALPANEL_CONNECTED_TO_1_TXT),DialNode -> Entry -> Header -> Name,NumberBuffer);
  252.     }
  253.     else
  254.     {
  255.         OnlinePlus = Config -> ModemConfig -> TimeToConnect;
  256.  
  257.         MakeCall("???",NumberBuffer);
  258.  
  259.         ObtainSemaphore(&PatternSemaphore);
  260.  
  261.         ChosenPattern = FindTimeDate(PatternList,NumberBuffer);
  262.  
  263.         SelectTime(NULL,ChosenPattern,NULL);
  264.  
  265.         ChosenEntry    = NULL;
  266.  
  267.         ReleaseSemaphore(&PatternSemaphore);
  268.  
  269.         CurrentPay    = 0;
  270.         Password[0]    = 0;
  271.         UserName[0]    = 0;
  272.         SendStartup    = FALSE;
  273.  
  274.         CurrentBBSName[0]    = 0;
  275.         CurrentBBSComment[0]    = 0;
  276.  
  277.         strcpy(CurrentBBSNumber,NumberBuffer);
  278.  
  279.         if(Config -> ModemConfig -> ConnectLimit > 0 && Config -> ModemConfig -> ConnectLimitMacro[0])
  280.         {
  281.             LimitCount = Config -> ModemConfig -> ConnectLimit;
  282.  
  283.             strcpy(LimitMacro,Config -> ModemConfig -> ConnectLimitMacro);
  284.         }
  285.         else
  286.             LimitCount = -1;
  287.  
  288.         LogAction(LocaleString(MSG_DIALPANEL_CONNECTED_TO_2_TXT),NumberBuffer);
  289.     }
  290.  
  291.         /* We are now online. */
  292.  
  293.     ObtainSemaphore(&OnlineSemaphore);
  294.  
  295.     Online = TRUE;
  296.  
  297.     ReleaseSemaphore(&OnlineSemaphore);
  298.  
  299.         /* Open auto-capture file. */
  300.  
  301.     if(Config -> CaptureConfig -> ConnectAutoCapture && Config -> CaptureConfig -> CapturePath[0])
  302.     {
  303.         if(DialNode -> Entry)
  304.             OpenAutoCaptureFile(DialNode -> Entry -> Header -> Name);
  305.         else
  306.             OpenAutoCaptureFile(LocaleString(MSG_DIALPANEL_CAPTURE_NAME_TXT));
  307.     }
  308.  
  309.         /* Remove node from
  310.          * dialing list and
  311.          * perform system
  312.          * setup.
  313.          */
  314.  
  315.     if(DialNode -> Entry)
  316.         RemoveDialNode(DialNode);
  317.  
  318.     Remove(&DialNode -> VanillaNode);
  319.  
  320.     FreeVecPooled(DialNode);
  321.  
  322.     if(PrivateConfig -> MiscConfig -> BackupConfig)
  323.     {
  324.         if(!BackupConfig)
  325.         {
  326.             if(BackupConfig = CreateConfiguration(TRUE))
  327.                 SaveConfig(PrivateConfig,BackupConfig);
  328.         }
  329.     }
  330.  
  331.         /* Make sure that the following
  332.          * setup/initialization will not
  333.          * touch the serial configuration.
  334.          */
  335.  
  336.     memcpy(PrivateConfig -> SerialConfig,Config -> SerialConfig,sizeof(struct SerialSettings));
  337.  
  338.     ConfigSetup();
  339.  
  340.         /* Reset the scanner. */
  341.  
  342.     FlowInit(TRUE);
  343. }
  344.  
  345.     /* OpenDialPanel(BOOL *Record):
  346.      *
  347.      *    Open the dialing panel.
  348.      */
  349.  
  350. STATIC LayoutHandle * __regargs
  351. OpenDialPanel(BOOL *Record)
  352. {
  353.     LayoutHandle *Handle;
  354.  
  355.     if(Handle = LT_CreateHandleTags(Window -> WScreen,
  356.         LH_LocaleHook,    &LocaleHook,
  357.     TAG_DONE))
  358.     {
  359.         LT_New(Handle,
  360.             LA_Type,    VERTICAL_KIND,
  361.         TAG_DONE);
  362.         {
  363.             LT_New(Handle,
  364.                 LA_Type,    VERTICAL_KIND,
  365.             TAG_DONE);
  366.             {
  367.                 LT_New(Handle,
  368.                     LA_Type,    VERTICAL_KIND,
  369.                 TAG_DONE);
  370.                 {
  371.                     LT_New(Handle,
  372.                         LA_Type,            BOX_KIND,
  373.                         LA_ID,                GAD_CALLING,
  374.                         LA_Chars,            45,
  375.                         LA_Lines,            4,
  376.                         LABX_ReserveSpace,    TRUE,
  377.                         LABX_FirstLabel,    MSG_DIALPANEL_CALLING_TXT,
  378.                         LABX_LastLabel,        MSG_DIALPANEL_NEXT_TXT,
  379.                     TAG_DONE);
  380.  
  381.                     LT_New(Handle,
  382.                         LA_Type,            BOX_KIND,
  383.                         LA_ID,                GAD_TIME,
  384.                         LA_Chars,            45,
  385.                         LA_Lines,            2,
  386.                         LABX_ReserveSpace,    TRUE,
  387.                         LABX_FirstLabel,    MSG_DIALPANEL_TIMEOUT_TXT,
  388.                         LABX_LastLabel,        MSG_DIALPANEL_ATTEMPT_TXT,
  389.                     TAG_DONE);
  390.  
  391.                     LT_New(Handle,
  392.                         LA_Type,            BOX_KIND,
  393.                         LA_ID,                GAD_NOTE,
  394.                         LA_Chars,            45,
  395.                         LA_Lines,            1,
  396.                         LABX_ReserveSpace,    TRUE,
  397.                         LABX_FirstLabel,    MSG_DIALPANEL_MESSAGE_TXT,
  398.                         LABX_LastLabel,        MSG_DIALPANEL_MESSAGE_TXT,
  399.                     TAG_DONE);
  400.  
  401.                     LT_EndGroup(Handle);
  402.                 }
  403.  
  404.                 LT_New(Handle,
  405.                     LA_Type,    VERTICAL_KIND,
  406.                 TAG_DONE);
  407.                 {
  408.                     LT_New(Handle,
  409.                         LA_Type,        XBAR_KIND,
  410.                     TAG_DONE);
  411.  
  412.                     LT_New(Handle,
  413.                         LA_Type,        CHECKBOX_KIND,
  414.                         LA_LabelID,        MSG_DIALPANEL_RECORD_ON_CONNECTION_TXT,
  415.                         LA_BOOL,        Record,
  416.                     TAG_DONE);
  417.  
  418.                     LT_EndGroup(Handle);
  419.                 }
  420.  
  421.                 LT_EndGroup(Handle);
  422.             }
  423.  
  424.             LT_New(Handle,
  425.                 LA_Type,VERTICAL_KIND,
  426.             TAG_DONE);
  427.             {
  428.                 LT_New(Handle,
  429.                     LA_Type,        XBAR_KIND,
  430.                     LAXB_FullSize,    TRUE,
  431.                 TAG_DONE);
  432.  
  433.                 LT_EndGroup(Handle);
  434.             }
  435.  
  436.             LT_New(Handle,LA_Type,HORIZONTAL_KIND,
  437.                 LAGR_Spread,    TRUE,
  438.             TAG_DONE);
  439.             {
  440.                 LT_New(Handle,
  441.                     LA_Type,        BUTTON_KIND,
  442.                     LA_LabelID,        MSG_DIALPANEL_SKIP_GAD,
  443.                     LA_ID,            GAD_SKIP,
  444.                     LABT_ExtraFat,    TRUE,
  445.                     GA_Disabled,    TRUE,
  446.                 TAG_DONE);
  447.  
  448.                 LT_New(Handle,
  449.                     LA_Type,        BUTTON_KIND,
  450.                     LA_LabelID,        MSG_GLOBAL_REMOVE_GAD,
  451.                     LA_ID,            GAD_REMOVE,
  452.                     LABT_ExtraFat,    TRUE,
  453.                     GA_Disabled,    TRUE,
  454.                 TAG_DONE);
  455.  
  456.                 LT_New(Handle,
  457.                     LA_Type,        BUTTON_KIND,
  458.                     LA_LabelID,        MSG_DIALPANEL_GO_TO_ONLINE_GAD,
  459.                     LA_ID,            GAD_ONLINE,
  460.                     LABT_ReturnKey,    TRUE,
  461.                     LABT_ExtraFat,    TRUE,
  462.                 TAG_DONE);
  463.  
  464.                 LT_New(Handle,
  465.                     LA_Type,        BUTTON_KIND,
  466.                     LA_LabelID,        MSG_GLOBAL_ABORT_GAD,
  467.                     LA_ID,            GAD_ABORT,
  468.                     LABT_ExtraFat,    TRUE,
  469.                 TAG_DONE);
  470.  
  471.                 LT_EndGroup(Handle);
  472.             }
  473.  
  474.             LT_EndGroup(Handle);
  475.         }
  476.  
  477.         if(LT_Build(Handle,
  478.             LAWN_TitleID,        MSG_DIALPANEL_DIALING_TXT,
  479.             LAWN_IDCMP,            IDCMP_CLOSEWINDOW,
  480.             LAWN_HelpHook,        &GuideHook,
  481.             LAWN_Parent,        Window,
  482.             WA_DepthGadget,        TRUE,
  483.             WA_CloseGadget,        TRUE,
  484.             WA_DragBar,            TRUE,
  485.             WA_RMBTrap,            TRUE,
  486.             WA_Activate,        TRUE,
  487.             WA_SimpleRefresh,    TRUE,
  488.         TAG_DONE))
  489.             return(Handle);
  490.         else
  491.             LT_DeleteHandle(Handle);
  492.     }
  493.  
  494.     return(NULL);
  495. }
  496.  
  497.     /* DialPanel():
  498.      *
  499.      *    This routine opens a small window in the middle of the
  500.      *    console window and walks down the list of numbers to
  501.      *    dial.
  502.      */
  503.  
  504. BOOL
  505. DialPanel()
  506. {
  507.     LayoutHandle    *Handle;
  508.     BOOL             Result = FALSE,
  509.                      Record = FALSE,
  510.                      DropIt = FALSE;
  511.  
  512.     BlockWindows();
  513.  
  514.     if(Handle = OpenDialPanel(&Record))
  515.     {
  516.         STATIC struct SerialSettings __far OriginalSerialConfig;
  517.  
  518.         struct Window        *PanelWindow = Handle -> Window;
  519.  
  520.         UBYTE                 ExitCommand[80],
  521.                              ExitBuffer[80],
  522.                               InitBuffer[80],
  523.                               PrefixBuffer[80],
  524.                               NumberBuffer[100];
  525.  
  526.         UBYTE                 DialBuffer[300];
  527.  
  528.         STRPTR                 NextExit,
  529.                              NextInit,
  530.                              NextPrefix,
  531.                              NextNumber;
  532.  
  533.         WORD                 NumberCount,
  534.                              NumberCurrent;
  535.  
  536.         LONG                 DialTimeout,
  537.                              DialRetries    = 0,
  538.                              DialAttempt    = 0;
  539.         struct PhoneNode    *DialNode        = NULL;
  540.  
  541.         LONG                 RedialTimeout;
  542.  
  543.         STRPTR                 CallingName;
  544.         UBYTE                 CallingBuffer[80];
  545.  
  546.         BOOL                 Dialing    = FALSE,
  547.                              Calling    = FALSE,
  548.                              Waiting    = FALSE,
  549.                              Skipping    = FALSE,
  550.                              Aborting    = FALSE,
  551.                              Error        = FALSE,
  552.                              Done        = FALSE,
  553.                              NeedHangUp    = TRUE;
  554.  
  555.         WORD                 RunCount    = 0;
  556.  
  557.         ULONG                 ODUMask;
  558.  
  559.             // Don't mix up the line send stuff with the default sending routine
  560.  
  561.         BYTE                (* LocalSendLine)(register STRPTR,register LONG);
  562.  
  563.         LocalSendLine    = SendLine;
  564.         SendLine        = SendLineDial;
  565.  
  566.             // Set up the ODU stuff
  567.  
  568.         if(OwnDevUnitBase && Config -> SerialConfig -> ReleaseODUWhenDialing && Config -> SerialConfig -> SatisfyODURequests != ODU_KEEP && !(Config -> SerialConfig -> Shared && Config -> SerialConfig -> NoODUIfShared) && OwnDevBit != -1)
  569.             ODUMask = (1L << OwnDevBit);
  570.         else
  571.             ODUMask = NULL;
  572.  
  573.             /* Reset the area code scanner data. */
  574.  
  575.         ObtainSemaphore(&PatternSemaphore);
  576.  
  577.         ChosenEntry        = NULL;
  578.         ChosenPattern    = NULL;
  579.  
  580.         ReleaseSemaphore(&PatternSemaphore);
  581.  
  582.             /* We are now dialing. */
  583.  
  584.         Status = STATUS_DIALING;
  585.  
  586.             /* Remember the original serial settings, so we
  587.              * can return to them later.
  588.              */
  589.  
  590.         CopyMem(Config -> SerialConfig,&OriginalSerialConfig,sizeof(struct SerialSettings));
  591.  
  592.             /* Set up the AmigaGuide help context. */
  593.  
  594.         GuideContext(CONTEXT_DIAL);
  595.  
  596.             /* No exit command is defined yet. */
  597.  
  598.         ExitCommand[0] = 0;
  599.  
  600.             /* Make the current one the active one. */
  601.  
  602.         LT_ShowWindow(Handle,TRUE);
  603.  
  604.         PushWindow(PanelWindow);
  605.  
  606.             /* Make a backup of the current configuration. */
  607.  
  608.         SaveConfig(Config,PrivateConfig);
  609.  
  610.             /* Don't echo serial output unless requested by the user. */
  611.  
  612.         if(!Config -> ModemConfig -> VerboseDialing)
  613.             Quiet = TRUE;
  614.  
  615.             /* Perform full sequence check. */
  616.  
  617.         FullCheck = TRUE;
  618.  
  619.             /* Reset the scanner. */
  620.  
  621.         FlowInit(TRUE);
  622.  
  623.             /* Clear the signals. */
  624.  
  625.         SetSignal(0,SIG_SKIP | SIG_BREAK);
  626.  
  627.             /* The big dialing loop. */
  628.  
  629.         do
  630.         {
  631.                 /* Abort the process? */
  632.  
  633.             if(SetSignal(0,SIG_BREAK) & SIG_BREAK)
  634.             {
  635.                 if(!Done)
  636.                     Aborting = Done = TRUE;
  637.             }
  638.  
  639.                 // Check if we should let go of the device
  640.  
  641.             if(ODUMask)
  642.             {
  643.                 if(SetSignal(0,0) & ODUMask)
  644.                 {
  645.                     if(!Done)
  646.                     {
  647.                         Aborting = Done = DropIt = TRUE;
  648.  
  649.                         SetSignal(0,ODUMask);
  650.                     }
  651.                 }
  652.             }
  653.  
  654.                 /* Any window input? */
  655.  
  656.             if(!Done && (SetSignal(0,PORTMASK(PanelWindow -> UserPort)) & PORTMASK(PanelWindow -> UserPort)))
  657.             {
  658.                 struct IntuiMessage    *Msg;
  659.                 ULONG                 MsgClass,
  660.                                      MsgQualifier;
  661.                 UWORD                 MsgCode;
  662.                 struct Gadget        *MsgGadget;
  663.  
  664.                 while(Msg = LT_GetIMsg(Handle))
  665.                 {
  666.                     MsgClass        = Msg -> Class;
  667.                     MsgCode            = Msg -> Code;
  668.                     MsgQualifier    = Msg -> Qualifier;
  669.                     MsgGadget        = Msg -> IAddress;
  670.  
  671.                     LT_ReplyIMsg(Msg);
  672.  
  673.                         /* Convert the space keypress into a
  674.                          * skip command.
  675.                          */
  676.  
  677.                     if(MsgClass == IDCMP_RAWKEY)
  678.                     {
  679.                         if((Dialing || Waiting) && LT_GetCode(MsgQualifier,MsgClass,MsgCode,MsgGadget) == ' ')
  680.                         {
  681.                             LT_PressButton(Handle,GAD_SKIP);
  682.  
  683.                             Skipping = TRUE;
  684.                         }
  685.                     }
  686.  
  687.                         /* Close the window, hang up the line,
  688.                          * return to the phone book.
  689.                          */
  690.  
  691.                     if(MsgClass == IDCMP_CLOSEWINDOW)
  692.                         Aborting = Done = Result = TRUE;
  693.  
  694.                         /* So a button was pressed. */
  695.  
  696.                     if(MsgClass == IDCMP_GADGETUP)
  697.                     {
  698.                         switch(MsgGadget -> GadgetID)
  699.                         {
  700.                                 /* Remove the currently active dialing
  701.                                  * list entry.
  702.                                  */
  703.  
  704.                             case GAD_REMOVE:
  705.  
  706.                                     /* This makes sense only while
  707.                                      * we are dialing.
  708.                                      */
  709.  
  710.                                 if(Dialing)
  711.                                 {
  712.                                     struct PhoneNode    *NextNode = NULL;
  713.                                     BOOL                 UseHangUp;
  714.  
  715.                                         /* If still dialing, hang up first. */
  716.  
  717.                                     if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  718.                                         UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  719.                                     else
  720.                                         UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  721.  
  722.                                     if(UseHangUp)
  723.                                         HangUp();
  724.                                     else
  725.                                     {
  726.                                         SerWrite("\r",1);
  727.  
  728.                                         WaitTime(1,0);
  729.                                     }
  730.  
  731.                                         /* Ignore the response of the modem. */
  732.  
  733.                                     HandleSerial();
  734.  
  735.                                     FlowInit(TRUE);
  736.  
  737.                                         /* Is there another entry in the list? */
  738.  
  739.                                     if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
  740.                                         NextNode = (struct PhoneNode *)DialNode -> VanillaNode . ln_Succ;
  741.                                     else
  742.                                     {
  743.                                             /* No, there isn't; do we have a list with
  744.                                              * at least two entries in it?
  745.                                              */
  746.  
  747.                                         if(DialList -> lh_Head -> ln_Succ -> ln_Succ)
  748.                                         {
  749.                                                 /* Yet another dialing attempt coming up... */
  750.  
  751.                                             DialAttempt++;
  752.  
  753.                                                 /* Check for dial retry limit. */
  754.  
  755.                                             if(DialRetries >= 0 && DialAttempt >= DialRetries)
  756.                                             {
  757.                                                 PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  758.  
  759.                                                 WakeUp(PanelWindow,SOUND_BELL);
  760.  
  761.                                                 WaitTime(2,0);
  762.  
  763.                                                 Say(LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  764.  
  765.                                                 Done = TRUE;
  766.                                             }
  767.                                             else
  768.                                             {
  769.                                                     /* Grab first list entry and continue. */
  770.  
  771.                                                 NextNode = (struct PhoneNode *)DialList -> lh_Head;
  772.                                             }
  773.                                         }
  774.                                         else
  775.                                         {
  776.                                                 /* That's all, folks! */
  777.  
  778.                                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIALING_LIST_IS_EMPTY_TXT));
  779.  
  780.                                             WaitTime(2,0);
  781.  
  782.                                             Done = TRUE;
  783.                                         }
  784.                                     }
  785.  
  786.                                         /* Remove dial entry from list. */
  787.  
  788.                                     if(DialNode -> Entry)
  789.                                         RemoveDialNode(DialNode);
  790.  
  791.                                     Remove(&DialNode -> VanillaNode);
  792.  
  793.                                     FreeVecPooled(DialNode);
  794.  
  795.                                         /* Is there an entry to proceed with? */
  796.  
  797.                                     if(DialNode = NextNode)
  798.                                     {
  799.                                         NextNumber = NULL;
  800.  
  801.                                         Calling = TRUE;
  802.                                     }
  803.                                 }
  804.  
  805.                                 break;
  806.  
  807.                             case GAD_SKIP:
  808.  
  809.                                 if(Dialing || Waiting)
  810.                                     Skipping = TRUE;
  811.  
  812.                                 break;
  813.  
  814.                             case GAD_ONLINE:
  815.  
  816.                                     /* Go online so soon? */
  817.  
  818.                                 if(!DialNode)
  819.                                 {
  820.                                     DialNode = (struct PhoneNode *)DialList -> lh_Head;
  821.  
  822.                                     if(DialNode -> Entry)
  823.                                         ExtractString(DialNode -> Entry -> Header -> Number,NumberBuffer,TRUE);
  824.                                     else
  825.                                         ExtractString(DialNode -> VanillaNode . ln_Name,NumberBuffer,TRUE);
  826.                                 }
  827.  
  828.                                 Connect(DialNode,NumberBuffer);
  829.  
  830.                                 Done = TRUE;
  831.  
  832.                                 break;
  833.  
  834.                                 /* Abort the dialing process. */
  835.  
  836.                             case GAD_ABORT:
  837.  
  838.                                 Aborting = Done = TRUE;
  839.  
  840.                                 break;
  841.                         }
  842.                     }
  843.  
  844.                     if(Done)
  845.                         break;
  846.                 }
  847.             }
  848.  
  849.                 /* Skip the current action? */
  850.  
  851.             if(SetSignal(0,SIG_SKIP) & SIG_SKIP)
  852.             {
  853.                 if((Dialing || Waiting) && !Done)
  854.                     Skipping = TRUE;
  855.             }
  856.  
  857.                 /* Are we to abort? */
  858.  
  859.             if(Aborting)
  860.             {
  861.                     /* Hang up if necessary. */
  862.  
  863.                 if(Dialing)
  864.                 {
  865.                     BOOL UseHangUp;
  866.  
  867.                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ABORTING_TXT));
  868.  
  869.                     if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  870.                         UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  871.                     else
  872.                         UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  873.  
  874.                     if(UseHangUp)
  875.                         HangUp();
  876.                     else
  877.                     {
  878.                         SerWrite("\r",1);
  879.                         WaitTime(1,0);
  880.                     }
  881.  
  882.                         /* Ignore the response of the modem. */
  883.  
  884.                     HandleSerial();
  885.  
  886.                     FlowInit(TRUE);
  887.                 }
  888.             }
  889.  
  890.                 /* Start at the beginning. */
  891.  
  892.             if(!DialNode && !Done)
  893.             {
  894.                 DialNode = (struct PhoneNode *)DialList -> lh_Head;
  895.  
  896.                 LT_SetAttributes(Handle,GAD_SKIP,
  897.                     GA_Disabled,    FALSE,
  898.                 TAG_DONE);
  899.  
  900.                 LT_SetAttributes(Handle,GAD_REMOVE,
  901.                     GA_Disabled,    FALSE,
  902.                 TAG_DONE);
  903.  
  904.                 Calling = TRUE;
  905.  
  906.                 NextNumber = NULL;
  907.             }
  908.  
  909.                 /* Are we to start a call? */
  910.  
  911.             if(Calling && !Done)
  912.             {
  913.                     /* Reset the sequence scanner, the user may have skipped
  914.                      * the previous dial attempt causing the modem to return
  915.                      * `NO CARRIER'. To prevent the dialer from skipping the
  916.                      * next dial entry as well as the previous we have to
  917.                      * flush any data pending on the serial line.
  918.                      */
  919.  
  920.                 FlowInit(TRUE);
  921.  
  922.                     /* Is this the first number for this dial entry? */
  923.  
  924.                 if(!NextNumber)
  925.                 {
  926.                     STRPTR    PhoneNumber;
  927.                     WORD    i,Len;
  928.  
  929.                         /* Does this entry have a configuration attached? */
  930.  
  931.                     if(DialNode -> Entry)
  932.                     {
  933.                             /* Get the phone number. */
  934.  
  935.                         PhoneNumber = DialNode -> Entry -> Header -> Number;
  936.  
  937.                             /* Pick up the modem configuration. */
  938.  
  939.                         if(DialNode -> Entry -> Config -> ModemConfig)
  940.                         {
  941.                             NextInit    = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> ModemInit,    InitBuffer,        FALSE);
  942.                             NextExit    = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> ModemExit,    ExitBuffer,        FALSE);
  943.                             NextPrefix    = ExtractString(DialNode -> Entry -> Config -> ModemConfig -> DialPrefix,    PrefixBuffer,    FALSE);
  944.                         }
  945.                         else
  946.                         {
  947.                             NextInit    = ExtractString(Config -> ModemConfig -> ModemInit,        InitBuffer,        FALSE);
  948.                             NextExit    = ExtractString(Config -> ModemConfig -> ModemExit,        ExitBuffer,        FALSE);
  949.                             NextPrefix    = ExtractString(Config -> ModemConfig -> DialPrefix,    PrefixBuffer,    FALSE);
  950.                         }
  951.                     }
  952.                     else
  953.                     {
  954.                             /* Get the phone number. */
  955.  
  956.                         PhoneNumber = DialNode -> VanillaNode . ln_Name;
  957.  
  958.                             /* Pick up the modem configuration. */
  959.  
  960.                         if(Config -> ModemConfig -> DoNotSendMainModemCommands)
  961.                             InitBuffer[0] = ExitBuffer[0] = 0;
  962.                         else
  963.                         {
  964.                             NextInit    = ExtractString(Config -> ModemConfig -> ModemInit,        InitBuffer,        FALSE);
  965.                             NextExit    = ExtractString(Config -> ModemConfig -> ModemExit,        ExitBuffer,        FALSE);
  966.                         }
  967.  
  968.                         NextPrefix = ExtractString(Config -> ModemConfig -> DialPrefix,    PrefixBuffer,    FALSE);
  969.                     }
  970.  
  971.                             /* Extract the phone number. */
  972.  
  973.                     NextNumber = ExtractString(PhoneNumber,NumberBuffer,TRUE);
  974.  
  975.                         /* Count the number of phone numbers separated
  976.                          * by "|" characters.
  977.                          */
  978.  
  979.                     Len = strlen(PhoneNumber);
  980.  
  981.                     for(i = 0, NumberCount = 0 ; i < Len ; i++)
  982.                     {
  983.                         if(PhoneNumber[i] == '|')
  984.                         {
  985.                             WORD j;
  986.  
  987.                             for(j = i + 1 ; j <= Len ; j++)
  988.                             {
  989.                                 if(PhoneNumber[j] != ' ' && PhoneNumber[j] != 0)
  990.                                 {
  991.                                     if(PhoneNumber[j] != '|')
  992.                                         NumberCount++;
  993.  
  994.                                     break;
  995.                                 }
  996.                             }
  997.                         }
  998.                     }
  999.  
  1000.                         /* This is the first one. */
  1001.  
  1002.                     NumberCurrent = 0;
  1003.                 }
  1004.                 else
  1005.                 {
  1006.                         /* Now for multiple phone numbers separated
  1007.                          * by `|' characters. If `NextNumber' happens
  1008.                          * to be zero, we will prepare to extract
  1009.                          * the first phone number from the list.
  1010.                          * In any other case we will try to obtain
  1011.                          * the next number.
  1012.                          */
  1013.  
  1014.                     NextNumber    = ExtractString(NextNumber,    NumberBuffer,    TRUE);
  1015.                     NextPrefix    = ExtractString(NextPrefix,    PrefixBuffer,    FALSE);
  1016.  
  1017.                     if(!DialNode -> Entry && Config -> ModemConfig -> DoNotSendMainModemCommands)
  1018.                         InitBuffer[0] = ExitBuffer[0] = 0;
  1019.                     else
  1020.                     {
  1021.                         NextInit    = ExtractString(NextInit,    InitBuffer,        FALSE);
  1022.                         NextExit    = ExtractString(NextExit,    ExitBuffer,        FALSE);
  1023.                     }
  1024.  
  1025.                     NumberCurrent++;
  1026.                 }
  1027.  
  1028.                     /* Send the modem exit string before we
  1029.                      * will need to reconfigure the serial
  1030.                      * device driver.
  1031.                      */
  1032.  
  1033.                 if(ExitCommand[0])
  1034.                     Error |= Done |= SendSomeCommand(Handle,ExitCommand,LocaleString(MSG_DIALPANEL_SENDING_MODEM_EXIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  1035.  
  1036.                     /* We will need to change the serial parameters
  1037.                      * in order to establish a connection.
  1038.                      */
  1039.  
  1040.                 if(!Done)
  1041.                 {
  1042.                     if(DialNode -> Entry && DialNode -> Entry -> Config -> SerialConfig)
  1043.                     {
  1044.                         if(ReconfigureSerial(PanelWindow,DialNode -> Entry -> Config -> SerialConfig) == RECONFIGURE_FAILURE)
  1045.                         {
  1046.                             WakeUp(PanelWindow,SOUND_ERROR);
  1047.  
  1048.                             Error = Done = TRUE;
  1049.                         }
  1050.                     }
  1051.                     else
  1052.                     {
  1053.                         if(ReconfigureSerial(PanelWindow,&OriginalSerialConfig) == RECONFIGURE_FAILURE)
  1054.                         {
  1055.                             WakeUp(PanelWindow,SOUND_ERROR);
  1056.  
  1057.                             Error = Done = TRUE;
  1058.                         }
  1059.                     }
  1060.                 }
  1061.  
  1062.                 if(!Done)
  1063.                 {
  1064.                         // Update the ODU stuff
  1065.  
  1066.                     if(OwnDevUnitBase && Config -> SerialConfig -> ReleaseODUWhenDialing && Config -> SerialConfig -> SatisfyODURequests != ODU_KEEP && !(Config -> SerialConfig -> Shared && Config -> SerialConfig -> NoODUIfShared) && OwnDevBit != -1)
  1067.                         ODUMask = (1L << OwnDevBit);
  1068.                     else
  1069.                         ODUMask = NULL;
  1070.  
  1071.                         /* Send the modem init command. */
  1072.  
  1073.                     if(InitBuffer[0])
  1074.                         Error |= Done |= SendSomeCommand(Handle,InitBuffer,LocaleString(MSG_DIALPANEL_SENDING_MODEM_INIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  1075.                 }
  1076.  
  1077.                 if(!Done)
  1078.                 {
  1079.                         /* Remember the new exit command. */
  1080.  
  1081.                     strcpy(ExitCommand,ExitBuffer);
  1082.  
  1083.                     if(DialNode -> Entry)
  1084.                         CallingName = DialNode -> Entry -> Header -> Name;
  1085.                     else
  1086.                         CallingName = LocaleString(MSG_GLOBAL_UNKNOWN_TXT);
  1087.  
  1088.                         /* If there is more than one number to follow, say so. */
  1089.  
  1090.                     if(NumberCount)
  1091.                     {
  1092.                         UBYTE LocalBuffer[40];
  1093.  
  1094.                         SPrintf(LocalBuffer,LocaleString(MSG_DIALPANEL_ATTEMPT_OF_TXT),NumberCurrent + 1,NumberCount + 1);
  1095.  
  1096.                         SPrintf(CallingBuffer,"%s (%s)",CallingName,LocalBuffer);
  1097.  
  1098.                         CallingName = CallingBuffer;
  1099.                     }
  1100.  
  1101.                     PrintBox(Handle,GAD_CALLING,0,CallingName);
  1102.  
  1103.                         /* Show the comment if any. */
  1104.  
  1105.                     if(DialNode -> Entry && DialNode -> Entry -> Header -> Comment[0])
  1106.                         PrintBox(Handle,GAD_CALLING,1,DialNode -> Entry -> Header -> Comment);
  1107.                     else
  1108.                         PrintBox(Handle,GAD_CALLING,1,"-");
  1109.  
  1110.                         /* Display the number being called. */
  1111.  
  1112.                     if(DialNode -> Entry)
  1113.                         Say(LocaleString(MSG_DIALPANEL_NOW_CALLING_TXT),DialNode -> Entry -> Header -> Name);
  1114.                     else
  1115.                         Say(LocaleString(MSG_DIALPANEL_NOW_CALLING_TXT),NumberBuffer);
  1116.  
  1117.                     PrintBox(Handle,GAD_CALLING,2,NumberBuffer);
  1118.  
  1119.                         /* Display the name of the service to call next. */
  1120.  
  1121.                     if(NextNumber)
  1122.                     {
  1123.                         if(DialNode -> Entry)
  1124.                             CallingName = DialNode -> Entry -> Header -> Name;
  1125.                         else
  1126.                             CallingName = DialNode -> VanillaNode . ln_Name;
  1127.                     }
  1128.                     else
  1129.                     {
  1130.                         if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
  1131.                         {
  1132.                             if(DialNode -> Entry)
  1133.                                 CallingName = ((struct PhoneNode *)DialNode -> VanillaNode . ln_Succ) -> Entry -> Header -> Name;
  1134.                             else
  1135.                                 CallingName = DialNode -> VanillaNode . ln_Succ -> ln_Name;
  1136.                         }
  1137.                         else
  1138.                             CallingName = "-";
  1139.                     }
  1140.  
  1141.                     PrintBox(Handle,GAD_CALLING,3,CallingName);
  1142.  
  1143.                         /* Right now we're dialing. */
  1144.  
  1145.                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIALING_TXT));
  1146.  
  1147.                         /* Build the dialing command. */
  1148.  
  1149.                     strcpy(DialBuffer,PrefixBuffer);
  1150.  
  1151.                     if(DialNode -> Entry && DialNode -> Entry -> Config -> ModemConfig)
  1152.                     {
  1153.                         if(DialNode -> Entry -> Config -> ModemConfig -> PBX_Mode && DialNode -> Entry -> Config -> ModemConfig -> PBX_Prefix[0])
  1154.                             strcat(DialBuffer,DialNode -> Entry -> Config -> ModemConfig -> PBX_Prefix);
  1155.                     }
  1156.                     else
  1157.                     {
  1158.                         if(Config -> ModemConfig -> PBX_Mode && Config -> ModemConfig -> PBX_Prefix[0])
  1159.                             strcat(DialBuffer,Config -> ModemConfig -> PBX_Prefix);
  1160.                     }
  1161.  
  1162.                     strcat(DialBuffer,NumberBuffer);
  1163.  
  1164.                     if(DialNode -> Entry)
  1165.                     {
  1166.                         if(DialNode -> Entry -> Config -> ModemConfig)
  1167.                             strcat(DialBuffer,DialNode -> Entry -> Config -> ModemConfig -> DialSuffix);
  1168.                         else
  1169.                             strcat(DialBuffer,Config -> ModemConfig -> DialSuffix);
  1170.                     }
  1171.                     else
  1172.                         strcat(DialBuffer,Config -> ModemConfig -> DialSuffix);
  1173.  
  1174.                         /* Pick up dial timeout and dial retries. */
  1175.  
  1176.                     if(DialNode -> Entry && DialNode -> Entry -> Config -> ModemConfig)
  1177.                     {
  1178.                         DialTimeout    = DialNode -> Entry -> Config -> ModemConfig -> DialTimeout;
  1179.                         DialRetries    = DialNode -> Entry -> Config -> ModemConfig -> DialRetries;
  1180.                     }
  1181.                     else
  1182.                     {
  1183.                         DialTimeout    = Config -> ModemConfig -> DialTimeout;
  1184.                         DialRetries    = Config -> ModemConfig -> DialRetries;
  1185.                     }
  1186.  
  1187.                         /* Dial the number. */
  1188.  
  1189.                     SerialCommand(DialBuffer);
  1190.  
  1191.                         /* Now we should be dialing. */
  1192.  
  1193.                     Calling = FALSE;
  1194.                     Dialing = TRUE;
  1195.  
  1196.                         /* For the sake of precision. */
  1197.  
  1198.                     RunCount = 0;
  1199.                 }
  1200.             }
  1201.  
  1202.                 /* Are we to skip the current assignment? */
  1203.  
  1204.             if(Skipping && !Done)
  1205.             {
  1206.                 Skipping = FALSE;
  1207.  
  1208.                     /* Are we currently dialing? */
  1209.  
  1210.                 if(Dialing)
  1211.                 {
  1212.                         /* Hang up if necessary. */
  1213.  
  1214.                     if(NeedHangUp)
  1215.                     {
  1216.                         BOOL UseHangUp;
  1217.  
  1218.                         if(DialNode -> Entry && DialNode -> Entry -> Config && DialNode -> Entry -> Config -> ModemConfig)
  1219.                             UseHangUp = DialNode -> Entry -> Config -> ModemConfig -> AbortHangsUp;
  1220.                         else
  1221.                             UseHangUp = Config -> ModemConfig -> AbortHangsUp;
  1222.  
  1223.                         if(UseHangUp)
  1224.                             HangUp();
  1225.                         else
  1226.                         {
  1227.                             SerWrite("\r",1);
  1228.                             WaitTime(1,0);
  1229.                         }
  1230.                     }
  1231.                     else
  1232.                         NeedHangUp = TRUE;
  1233.  
  1234.                         /* Ignore the response of the modem. */
  1235.  
  1236.                     HandleSerial();
  1237.  
  1238.                     FlowInit(TRUE);
  1239.  
  1240.                         /* Did we dial all the numbers available? */
  1241.  
  1242.                     if(!NextNumber)
  1243.                     {
  1244.                             /* Is this one the last entry? */
  1245.  
  1246.                         if(DialNode -> VanillaNode . ln_Succ -> ln_Succ)
  1247.                         {
  1248.                             LONG InterDialDelay;
  1249.  
  1250.                                 /* There is still another entry. */
  1251.  
  1252.                             DialNode = (struct PhoneNode *)DialNode -> VanillaNode . ln_Succ;
  1253.  
  1254.                                 /* Get the inter-dial delay. */
  1255.  
  1256.                             if(DialNode -> Entry)
  1257.                             {
  1258.                                 if(DialNode -> Entry -> Config -> ModemConfig)
  1259.                                     InterDialDelay = DialNode -> Entry -> Config -> ModemConfig -> InterDialDelay;
  1260.                                 else
  1261.                                     InterDialDelay = Config -> ModemConfig -> InterDialDelay;
  1262.                             }
  1263.                             else
  1264.                                 InterDialDelay = Config -> ModemConfig -> InterDialDelay;
  1265.  
  1266.                                 /* Check if we should wait before we fire off another dial command. */
  1267.  
  1268.                             if(InterDialDelay)
  1269.                             {
  1270.                                     /* Wait until the inter-dial delay has elapsed. */
  1271.  
  1272.                                 RedialTimeout = InterDialDelay;
  1273.  
  1274.                                 PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_WAITING_TO_CALL_TXT));
  1275.  
  1276.                                 Dialing = FALSE;
  1277.                                 Waiting = TRUE;
  1278.  
  1279.                                     /* For the sake of precision. */
  1280.  
  1281.                                 RunCount = 0;
  1282.  
  1283.                                 Say(LocaleString(MSG_DIALPANEL_WAITING_TXT));
  1284.  
  1285.                                     /* No entry is currently being called. */
  1286.  
  1287.                                 PrintBox(Handle,GAD_CALLING,0,"-");
  1288.                                 PrintBox(Handle,GAD_CALLING,1,"-");
  1289.                                 PrintBox(Handle,GAD_CALLING,2,"-");
  1290.  
  1291.                                 LT_SetAttributes(Handle,GAD_REMOVE,
  1292.                                     GA_Disabled,    TRUE,
  1293.                                 TAG_DONE);
  1294.  
  1295.                                     /* Display name of entry to call next. */
  1296.  
  1297.                                 if(DialNode -> Entry)
  1298.                                     PrintBox(Handle,GAD_CALLING,3,DialNode -> Entry -> Header -> Name);
  1299.                                 else
  1300.                                     PrintBox(Handle,GAD_CALLING,3,LocaleString(MSG_GLOBAL_UNKNOWN_TXT));
  1301.                             }
  1302.                             else
  1303.                             {
  1304.                                 Dialing = FALSE;
  1305.                                 Calling = TRUE;
  1306.                             }
  1307.                         }
  1308.                         else
  1309.                         {
  1310.                                 /* Yet another dial attempt coming up. */
  1311.  
  1312.                             DialAttempt++;
  1313.  
  1314.                                 /* Is this one the last dial
  1315.                                  * attempt to be made?
  1316.                                  */
  1317.  
  1318.                             if(DialAttempt >= DialRetries && DialRetries >= 0)
  1319.                             {
  1320.                                 PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  1321.  
  1322.                                 WakeUp(PanelWindow,SOUND_BELL);
  1323.  
  1324.                                 WaitTime(2,0);
  1325.  
  1326.                                 Say(LocaleString(MSG_DIALPANEL_MAXIMUM_NUMBER_OF_DIAL_RETRIES_TXT));
  1327.  
  1328.                                 Done = TRUE;
  1329.                             }
  1330.                             else
  1331.                             {
  1332.                                 LONG InterDialDelay;
  1333.  
  1334.                                     /* Get the first list entry. */
  1335.  
  1336.                                 DialNode = (struct PhoneNode *)DialList -> lh_Head;
  1337.  
  1338.                                 NextNumber = NULL;
  1339.  
  1340.                                     /* Get the redial delay. */
  1341.  
  1342.                                 if(DialNode -> Entry)
  1343.                                 {
  1344.                                     if(DialNode -> Entry -> Config -> ModemConfig)
  1345.                                     {
  1346.                                         RedialTimeout    = DialNode -> Entry -> Config -> ModemConfig -> RedialDelay;
  1347.                                         InterDialDelay    = DialNode -> Entry -> Config -> ModemConfig -> InterDialDelay;
  1348.                                     }
  1349.                                     else
  1350.                                     {
  1351.                                         RedialTimeout    = Config -> ModemConfig -> RedialDelay;
  1352.                                         InterDialDelay    = Config -> ModemConfig -> InterDialDelay;
  1353.                                     }
  1354.                                 }
  1355.                                 else
  1356.                                 {
  1357.                                     RedialTimeout    = Config -> ModemConfig -> RedialDelay;
  1358.                                     InterDialDelay    = Config -> ModemConfig -> InterDialDelay;
  1359.                                 }
  1360.  
  1361.                                     /* Check if the inter-dial delay is larger than
  1362.                                      * the redial delay. If so, use the inter-dial delay.
  1363.                                      */
  1364.  
  1365.                                 if(InterDialDelay > RedialTimeout)
  1366.                                     RedialTimeout = InterDialDelay;
  1367.  
  1368.                                     /* No redial delay? Restart dialing... */
  1369.  
  1370.                                 if(!RedialTimeout)
  1371.                                 {
  1372.                                     Dialing = FALSE;
  1373.                                     Calling = TRUE;
  1374.  
  1375.                                     WaitTime(1,0);
  1376.                                 }
  1377.                                 else
  1378.                                 {
  1379.                                         /* Go into redial delay. */
  1380.  
  1381.                                     PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_REDIAL_DELAY_TXT));
  1382.  
  1383.                                     Dialing = FALSE;
  1384.                                     Waiting = TRUE;
  1385.  
  1386.                                         /* For the sake of precision. */
  1387.  
  1388.                                     RunCount = 0;
  1389.  
  1390.                                     Say(LocaleString(MSG_DIALPANEL_WAITING_TXT));
  1391.  
  1392.                                         /* No entry is currently being called. */
  1393.  
  1394.                                     PrintBox(Handle,GAD_CALLING,0,"-");
  1395.                                     PrintBox(Handle,GAD_CALLING,1,"-");
  1396.                                     PrintBox(Handle,GAD_CALLING,2,"-");
  1397.  
  1398.                                     LT_SetAttributes(Handle,GAD_REMOVE,
  1399.                                         GA_Disabled,    TRUE,
  1400.                                     TAG_DONE);
  1401.  
  1402.                                         /* Display name of entry to call next. */
  1403.  
  1404.                                     if(DialNode -> Entry)
  1405.                                         PrintBox(Handle,GAD_CALLING,3,DialNode -> Entry -> Header -> Name);
  1406.                                     else
  1407.                                         PrintBox(Handle,GAD_CALLING,3,LocaleString(MSG_GLOBAL_UNKNOWN_TXT));
  1408.                                 }
  1409.                             }
  1410.                         }
  1411.                     }
  1412.                     else
  1413.                     {
  1414.                         LONG InterDialDelay;
  1415.  
  1416.                             /* Get the inter-dial delay. */
  1417.  
  1418.                         if(DialNode -> Entry)
  1419.                         {
  1420.                             if(DialNode -> Entry -> Config -> ModemConfig)
  1421.                                 InterDialDelay = DialNode -> Entry -> Config -> ModemConfig -> InterDialDelay;
  1422.                             else
  1423.                                 InterDialDelay = Config -> ModemConfig -> InterDialDelay;
  1424.                         }
  1425.                         else
  1426.                             InterDialDelay = Config -> ModemConfig -> InterDialDelay;
  1427.  
  1428.                             /* Check if we should wait before we fire off another dial command. */
  1429.  
  1430.                         if(InterDialDelay)
  1431.                         {
  1432.                                 /* Wait until the inter-dial delay has elapsed. */
  1433.  
  1434.                             RedialTimeout = InterDialDelay;
  1435.  
  1436.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_WAITING_TO_CALL_TXT));
  1437.  
  1438.                             Dialing = FALSE;
  1439.                             Waiting = TRUE;
  1440.  
  1441.                                 /* For the sake of precision. */
  1442.  
  1443.                             RunCount = 0;
  1444.  
  1445.                             Say(LocaleString(MSG_DIALPANEL_WAITING_TXT));
  1446.  
  1447.                                 /* No entry is currently being called. */
  1448.  
  1449.                             PrintBox(Handle,GAD_CALLING,0,"-");
  1450.                             PrintBox(Handle,GAD_CALLING,1,"-");
  1451.                             PrintBox(Handle,GAD_CALLING,2,"-");
  1452.  
  1453.                             LT_SetAttributes(Handle,GAD_REMOVE,
  1454.                                 GA_Disabled,    TRUE,
  1455.                             TAG_DONE);
  1456.  
  1457.                                 /* Display name of entry to call next. */
  1458.  
  1459.                             if(DialNode -> Entry)
  1460.                                 PrintBox(Handle,GAD_CALLING,3,DialNode -> Entry -> Header -> Name);
  1461.                             else
  1462.                                 PrintBox(Handle,GAD_CALLING,3,LocaleString(MSG_GLOBAL_UNKNOWN_TXT));
  1463.                         }
  1464.                         else
  1465.                         {
  1466.                             Dialing = FALSE;
  1467.                             Calling = TRUE;
  1468.                         }
  1469.                     }
  1470.                 }
  1471.                 else
  1472.                 {
  1473.                         /* Stop waiting. */
  1474.  
  1475.                     if(Waiting)
  1476.                     {
  1477.                         LT_SetAttributes(Handle,GAD_REMOVE,
  1478.                             GA_Disabled,    FALSE,
  1479.                         TAG_DONE);
  1480.  
  1481.                         Waiting = FALSE;
  1482.                         Calling = TRUE;
  1483.                     }
  1484.                 }
  1485.             }
  1486.  
  1487.                 /* Take care of serial input. */
  1488.  
  1489.             if(!Done)
  1490.                 HandleSerial();
  1491.  
  1492.                 /* Any news from the modem? */
  1493.  
  1494.             if(!Done && FlowInfo . Changed)
  1495.             {
  1496.                     /* Current number is busy. */
  1497.  
  1498.                 if(FlowInfo . Busy || (FlowInfo . NoCarrier && Config -> ModemConfig -> NoCarrierIsBusy))
  1499.                 {
  1500.                     FlowInit(TRUE);
  1501.  
  1502.                     if(Dialing && !Done)
  1503.                     {
  1504.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_LINE_IS_BUSY_TXT));
  1505.  
  1506.                         Say(LocaleString(MSG_DIALPANEL_LINE_IS_BUSY_TXT));
  1507.  
  1508.                         WaitTime(1,0);
  1509.  
  1510.                         Skipping = TRUE;
  1511.  
  1512.                         NeedHangUp = FALSE;
  1513.                     }
  1514.                 }
  1515.  
  1516.                     /* Line does not feature a dialtone. */
  1517.  
  1518.                 if(FlowInfo . NoDialTone)
  1519.                 {
  1520.                     FlowInit(TRUE);
  1521.  
  1522.                     if(Dialing && !Done)
  1523.                     {
  1524.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_NO_DIALTONE_TXT));
  1525.  
  1526.                         WakeUp(PanelWindow,SOUND_ERROR);
  1527.  
  1528.                         Say(LocaleString(MSG_DIALPANEL_NO_DIALTONE_TXT));
  1529.  
  1530.                         Error = Done = TRUE;
  1531.                     }
  1532.                 }
  1533.  
  1534.                     /* Somebody tries to call us. */
  1535.  
  1536.                 if(FlowInfo . Ring)
  1537.                 {
  1538.                     FlowInit(TRUE);
  1539.  
  1540.                     if(!Done)
  1541.                     {
  1542.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  1543.  
  1544.                         WakeUp(PanelWindow,SOUND_RING);
  1545.  
  1546.                         Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  1547.  
  1548.                         Error = Done = TRUE;
  1549.                     }
  1550.                 }
  1551.  
  1552.                     /* Somebody's talking. */
  1553.  
  1554.                 if(FlowInfo . Voice)
  1555.                 {
  1556.                     FlowInit(TRUE);
  1557.  
  1558.                     if(!Done)
  1559.                     {
  1560.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_INCOMING_VOICE_CALL_TXT));
  1561.  
  1562.                         WakeUp(PanelWindow,SOUND_VOICE);
  1563.  
  1564.                         Say(LocaleString(MSG_DIALPANEL_INCOMING_VOICE_CALL_TXT));
  1565.  
  1566.                         Error = Done = TRUE;
  1567.                     }
  1568.                 }
  1569.  
  1570.                     /* We got a connect. */
  1571.  
  1572.                 if(FlowInfo . Connect)
  1573.                 {
  1574.                     FlowInit(TRUE);
  1575.  
  1576.                     if(Dialing && !Done)
  1577.                     {
  1578.                             /* Make the connection. */
  1579.  
  1580.                         Connect(DialNode,NumberBuffer);
  1581.  
  1582.                         Done = TRUE;
  1583.  
  1584.                             /* Wake the user up. */
  1585.  
  1586.                         if(BaudBuffer[0])
  1587.                         {
  1588.                             PrintBox(Handle,GAD_NOTE,0,"CONNECT %s",BaudBuffer);
  1589.  
  1590.                             WakeUp(PanelWindow,SOUND_CONNECT);
  1591.  
  1592.                             WaitTime(2,0);
  1593.  
  1594.                                 /* Install new baud rate if desired. */
  1595.  
  1596.                             if(Config -> ModemConfig -> ConnectAutoBaud && DTERate > 110)
  1597.                             {
  1598.                                 Config -> SerialConfig -> BaudRate = DTERate;
  1599.  
  1600.                                 ReconfigureSerial(PanelWindow,NULL);
  1601.                             }
  1602.                         }
  1603.                         else
  1604.                         {
  1605.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_CONNECTION_ESTABLISHED_TXT));
  1606.  
  1607.                             WakeUp(PanelWindow,SOUND_CONNECT);
  1608.                         }
  1609.  
  1610.                         Say(LocaleString(MSG_DIALPANEL_CONNECTION_ESTABLISHED_TXT));
  1611.                     }
  1612.                 }
  1613.  
  1614.                     /* Looks like an error. */
  1615.  
  1616.                 if(FlowInfo . Error)
  1617.                 {
  1618.                     FlowInit(TRUE);
  1619.  
  1620.                     if(Dialing && !Done)
  1621.                     {
  1622.                         PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  1623.  
  1624.                         WakeUp(PanelWindow,SOUND_ERROR);
  1625.  
  1626.                         Error = Done = TRUE;
  1627.                     }
  1628.                 }
  1629.  
  1630.                     /* In any other case, reset the scanner. */
  1631.  
  1632.                 FlowInit(TRUE);
  1633.             }
  1634.  
  1635.                 /* If nothing special's up... */
  1636.  
  1637.             if(!Done && !Skipping && (Dialing || Waiting))
  1638.             {
  1639.                     /* Wait half a second. */
  1640.  
  1641.                 WaitTime(0,MILLION / 2);
  1642.  
  1643.                 if(Dialing)
  1644.                 {
  1645.                     PrintBox(Handle,GAD_TIME,0,"%2ld:%02ld",DialTimeout / 60,DialTimeout % 60);
  1646.  
  1647.                     if(DialRetries < 0)
  1648.                         PrintBox(Handle,GAD_TIME,1,LocaleString(MSG_DIAL_RETRIES_UNLIMITED_TXT));
  1649.                     else
  1650.                         PrintBox(Handle,GAD_TIME,1,LocaleString(MSG_DIALPANEL_ATTEMPT_OF_TXT),DialAttempt + 1,DialRetries);
  1651.                 }
  1652.  
  1653.                 if(Waiting)
  1654.                     PrintBox(Handle,GAD_TIME,0,"%2ld:%02ld",RedialTimeout / 60,RedialTimeout % 60);
  1655.  
  1656.                     /* The following instructions are executed each second */
  1657.  
  1658.                 if(RunCount++)
  1659.                 {
  1660.                     RunCount = 0;
  1661.  
  1662.                         /* Are we dialing? */
  1663.  
  1664.                     if(Dialing)
  1665.                     {
  1666.                             /* Yet another second has elapsed. */
  1667.  
  1668.                         if(DialTimeout > 0)
  1669.                             DialTimeout--;
  1670.  
  1671.                             /* Has the dial timeout elapsed without
  1672.                              * a connection being made?
  1673.                              */
  1674.  
  1675.                         if(!DialTimeout)
  1676.                         {
  1677.                             PrintBox(Handle,GAD_NOTE,0,LocaleString(MSG_DIALPANEL_DIAL_ATTEMPT_TIMEOUT_TXT));
  1678.  
  1679.                             Skipping = TRUE;
  1680.                         }
  1681.                     }
  1682.  
  1683.                         /* Are we waiting? */
  1684.  
  1685.                     if(Waiting)
  1686.                     {
  1687.                             /* Yet another second has elapsed. */
  1688.  
  1689.                         if(RedialTimeout > 0)
  1690.                             RedialTimeout--;
  1691.  
  1692.                             /* The redial delay has elapsed,
  1693.                              * start dialing again.
  1694.                              */
  1695.  
  1696.                         if(!RedialTimeout)
  1697.                             Skipping = TRUE;
  1698.                     }
  1699.                 }
  1700.             }
  1701.         }
  1702.         while(!Done);
  1703.  
  1704.             /* Are we online or not? */
  1705.  
  1706.         ObtainSemaphore(&OnlineSemaphore);
  1707.  
  1708.         if(!Online)
  1709.         {
  1710.             BOOL SendCommands = TRUE;
  1711.  
  1712.             ReleaseSemaphore(&OnlineSemaphore);
  1713.  
  1714.                 /* Is the serial setup different? */
  1715.  
  1716.             if(memcmp(Config -> SerialConfig,&OriginalSerialConfig,sizeof(struct SerialSettings)))
  1717.             {
  1718.                     /* Set up the old serial configuration. */
  1719.  
  1720.                 if(ReconfigureSerial(PanelWindow,&OriginalSerialConfig) == RECONFIGURE_FAILURE)
  1721.                     SendCommands = FALSE;
  1722.             }
  1723.  
  1724.             if(SendCommands)
  1725.             {
  1726.                     /* Send the exit command if necessary. */
  1727.  
  1728.                 if(ExitCommand[0])
  1729.                     Error |= SendSomeCommand(Handle,ExitCommand,LocaleString(MSG_DIALPANEL_SENDING_MODEM_EXIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  1730.  
  1731.                     /* Take care of the init command if necessary. */
  1732.  
  1733.                 if(Config -> ModemConfig -> ModemInit[0] && !Error)
  1734.                     Error |= SendSomeCommand(Handle,Config -> ModemConfig -> ModemInit,LocaleString(MSG_DIALPANEL_SENDING_MODEM_INIT_COMMAND_TXT),LocaleString(MSG_DIALPANEL_ERROR_SENDING_MODEM_COMMAND_TXT));
  1735.             }
  1736.         }
  1737.         else
  1738.             ReleaseSemaphore(&OnlineSemaphore);
  1739.  
  1740.             /* Make sure the error gets displayed. */
  1741.  
  1742.         if(Error && !DropIt)
  1743.         {
  1744.             struct IntuiMessage    *Msg;
  1745.             ULONG                 MsgClass;
  1746.             WORD                 i;
  1747.  
  1748.             for(i = GAD_SKIP ; i <= GAD_REMOVE ; i++)
  1749.                 LT_SetAttributes(Handle,i,GA_Disabled,TRUE,TAG_DONE);
  1750.  
  1751.             Done = FALSE;
  1752.  
  1753.             do
  1754.             {
  1755.                 if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
  1756.                     break;
  1757.  
  1758.                 while(Msg = LT_GetIMsg(Handle))
  1759.                 {
  1760.                     MsgClass = Msg -> Class;
  1761.  
  1762.                     LT_ReplyIMsg(Msg);
  1763.  
  1764.                     if(MsgClass == IDCMP_CLOSEWINDOW || MsgClass == IDCMP_GADGETUP)
  1765.                         Done = TRUE;
  1766.                 }
  1767.             }
  1768.             while(!Done);
  1769.         }
  1770.  
  1771.             // Put back the old routine if necessary
  1772.  
  1773.         if(SendLine == SendLineDial)
  1774.             SendLine = LocalSendLine;
  1775.  
  1776.         PopWindow();
  1777.  
  1778.         LT_DeleteHandle(Handle);
  1779.  
  1780.             /* Reset the scanner. */
  1781.  
  1782.         FullCheck = FALSE;
  1783.  
  1784.         FlowInit(TRUE);
  1785.  
  1786.             /* We are done now, restart echoing serial */
  1787.  
  1788.         Quiet = FALSE;
  1789.  
  1790.         ReleaseWindows();
  1791.  
  1792.             /* Reset the display if necessary. */
  1793.  
  1794.         if(ResetDisplay)
  1795.         {
  1796.             if(!DisplayReset())
  1797.                 return(FALSE);
  1798.         }
  1799.  
  1800.             /* Handle online jobs. */
  1801.  
  1802.         ObtainSemaphore(&OnlineSemaphore);
  1803.  
  1804.         if(Online)
  1805.         {
  1806.             ReleaseSemaphore(&OnlineSemaphore);
  1807.  
  1808.             SetDialMenu(FALSE);
  1809.  
  1810.                 /* Send the startup macro if necessary. */
  1811.  
  1812.             if(SendStartup)
  1813.             {
  1814.                 if(Config -> CommandConfig -> LoginMacro[0])
  1815.                     SerialCommand(Config -> CommandConfig -> LoginMacro);
  1816.  
  1817.                 if(Config -> CommandConfig -> StartupMacro[0])
  1818.                     SerialCommand(Config -> CommandConfig -> StartupMacro);
  1819.  
  1820.                 SendStartup = FALSE;
  1821.             }
  1822.  
  1823.                 /* Take care of the recording feature. */
  1824.  
  1825.             if(Record)
  1826.             {
  1827.                 if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : CurrentBBSNumber))
  1828.                 {
  1829.                     RememberResetOutput();
  1830.                     RememberResetInput();
  1831.  
  1832.                     RememberOutput = TRUE;
  1833.  
  1834.                     Recording = TRUE;
  1835.                     RecordingLine = FALSE;
  1836.  
  1837.                     OnItem(MEN_RECORD_LINE);
  1838.  
  1839.                     CheckItem(MEN_RECORD,TRUE);
  1840.                     CheckItem(MEN_RECORD_LINE,FALSE);
  1841.                 }
  1842.             }
  1843.         }
  1844.         else
  1845.         {
  1846.             ReleaseSemaphore(&OnlineSemaphore);
  1847.  
  1848.             SetDialMenu(TRUE);
  1849.         }
  1850.     }
  1851.     else
  1852.         ReleaseWindows();
  1853.  
  1854.         /* Reply to the message that started the
  1855.          * dialing process.
  1856.          */
  1857.  
  1858.     ObtainSemaphore(&OnlineSemaphore);
  1859.  
  1860.     Forbid();
  1861.  
  1862.     if(DialMsg)
  1863.     {
  1864.         if(Online)
  1865.             DialMsg -> rm_Result1 = RC_OK;
  1866.         else
  1867.             DialMsg -> rm_Result1 = RC_WARN;
  1868.  
  1869.         DialMsg -> rm_Result2 = 0;
  1870.  
  1871.         ReplyMsg(DialMsg);
  1872.  
  1873.         DialMsg = NULL;
  1874.     }
  1875.  
  1876.     Permit();
  1877.  
  1878.     ReleaseSemaphore(&OnlineSemaphore);
  1879.  
  1880.     if(DropIt)
  1881.         HandleOwnDevUnit();
  1882.  
  1883.     return(Result);
  1884. }
  1885.